goog.provide('Editor');

goog.require('Photo');
goog.require('LocationPopup');
goog.require('ObjectList');

goog.require('goog.Uri');
goog.require('goog.Uri.QueryData');
goog.require('goog.dom');
goog.require('goog.dom.forms');
goog.require('goog.style');
goog.require('goog.events');
goog.require('goog.net.XhrIo');


/**
 * @constructor
 */
Editor = function(photo) {
    this.photo = photo;
    this.dirty = false;

    var parentContainer = goog.dom.getElement('all-photos');
    var templateNode = goog.dom.getElement('editor-template');
    this.editorElement = templateNode.cloneNode(true);
    this.editorContainer = goog.dom.getElementsByTagNameAndClass(
	'div', 'editor-container', this.editorElement)[0];
    this.refreshButton = goog.dom.getElementsByTagNameAndClass(
	'button', 'refresh-button', this.editorElement)[0];
    this.form = goog.dom.getElementsByTagNameAndClass(
	'form', null, this.editorElement)[0];

    // Init some widgets in the editor.
    this.objectLists = Object();
    this.initObjectList('entity');
    this.initObjectList('tag');
    this.initObjectList('medium');

    this.installEventHandlers();

    // Make it "showable".
    this.showMessage('Loading, please wait...');
    goog.dom.appendChild(parentContainer, this.editorElement);

    // Kick off the data load.
    this.load();
};

Editor.prototype.initObjectList = function(baseName) {
    var list = new ObjectList(
	baseName,
	goog.dom.getElementsByTagNameAndClass(
	    'div', baseName + '-list', this.editorElement)[0]);
    goog.events.listen(
	goog.dom.getElementsByTagNameAndClass(
	    'button', 'add-' + baseName + '-button', this.editorElement)[0],
	goog.events.EventType.CLICK,
	goog.bind(function(list) {
	    var newEntry = goog.dom.getElementsByTagNameAndClass(
		'input', baseName + '-input', this.editorElement)[0];
	    if (newEntry.value.trim().length == 0) {
		newEntry.value = '';
		return;
	    }
	    list.addElement(newEntry.value);
	    newEntry.value = '';
	    return false;
	}, this, list));
    this.objectLists[baseName] = list;
};

Editor.prototype.installEventHandlers = function() {
    goog.events.listen(
	goog.dom.getElementsByTagNameAndClass(
	    'button', 'update-button', this.editorElement)[0],
	goog.events.EventType.CLICK,
	function() {
	    this.update();
	    return false;
	}, false, this);

    // The lat/long widget needs some special event handling.
    goog.events.listen(
	goog.dom.getElementsByTagNameAndClass(
	    'button', 'select-latlong', this.editorElement)[0],
	goog.events.EventType.CLICK,
	goog.bind(function() {
	    LocationPopup.show(
		this.form['latitude'].value,
		this.form['longitude'].value,
		goog.bind(this.locationUpdate, this));
	}, this));
}

Editor.prototype.locationUpdate = function(latitude, longitude) {
    this.form['latitude'].value = latitude;
    this.form['longitude'].value = longitude;
};

Editor.prototype.update = function() {
    var formData = goog.dom.forms.getFormDataString(this.form);
    goog.net.XhrIo.send('/catalog/update', goog.bind(function(e) {
	var xhr = e.target;
	if (!xhr.isSuccess()) {
	    this.showMessage('Save failed, please retry.', true);
	    return;
	}
	this.showMessage('Save succeeded.');
    }, this), 'POST', formData);
};

Editor.prototype.setFormValues = function(o) {
    // The JSON attribute names are all CamelCase. We need to ignore that.
    for (var k in o) {
	var formField = k.toLowerCase();
	var list = this.objectLists[formField];
	if (list) {
	    // Initialise this field as an object list.
	    for (var index in o[k]) {
		list.addElement(o[k][index]);
	    }
	    continue;
	} 
	// Just a simple flat field.
	try {
	    this.form[formField].value = o[k];
	} catch(ex) {
	    window.console.log('Could not assign ' + formField + '.');
	}
    }

};

Editor.prototype.load = function(dataUrl) {
    // Some properties are auto-populated.
    var picUrlElement = goog.dom.getElementsByTagNameAndClass(
	'input', 'input-picurl', this.editorElement)[0];
    var catalogIdElement = goog.dom.getElementsByTagNameAndClass(
	'input', 'catalog-id', this.editorElement)[0];
    picUrlElement.value = this.photo.imageUrl;
    catalogIdElement.value = this.photo.photoId;

    // For the rest, we load them from the catalog if they exist.
    var loadUrl = '/catalog/read?catalog-id=' + this.photo.photoId;
    goog.net.XhrIo.send(loadUrl, goog.bind(function(e) {
	var xhr = e.target;
	if (!xhr.isSuccess()) {
	    this.showMessage('Load failed, please hit refresh to retry.', true);
	    goog.style.showElement(this.refreshButton, true);
	    return;
	}

	var responseJson = null;
	try {
	    responseJson = xhr.getResponseJson();
	} catch(ex) {
	    goog.style.showElement(this.refreshButton, true);
	    goog.style.showElement(this.editorContainer, false);
	    this.showMessage('Load returned bad data.', true);
	    return;
	}
	this.setFormValues(responseJson);
	goog.style.showElement(this.editorContainer, true);
	goog.style.showElement(this.refreshButton, false);
	this.showMessage('Load succeeded.');
    }, this), 'GET');
};

Editor.prototype.showMessage = function(message, failure) {
    var statusElement = goog.dom.getElementsByTagNameAndClass(
	'div', 'status-message', this.editorElement)[0];
    goog.dom.setTextContent(statusElement, message);
    if (failure) {
	goog.dom.classes.addRemove(
	    statusElement, 'status-success', 'status-failure');
    } else {
	goog.dom.classes.addRemove(
	    statusElement, 'status-failure', 'status-success');
    }
};

Editor.prototype.show = function() {
    var imgElement = goog.dom.getElementsByTagNameAndClass(
	'img', 'thumbnail', this.editorElement)[0];
    imgElement.src = this.photo.imageUrl;
    goog.style.showElement(this.editorElement, true);  
};